// File:   ButtonCode.asm
// Created:  Marcin 18, 2009
// Creator:  Marcin Misiewicz
//
// DESCRIPTION:
//   Controls button presses and returns events of presses (up/down/left/right/enter)
/////////////////////////////////////////////////////////////////
//*******CRITICAL******** for integration: The following configuration for GPIO ports needs to be placed into the main setup thread.
//LCD is connected to to A0 LCDRx (cfg=1 output pin on whmboard),A1 LCDTx (cfg=0 input pin on whboard), need to set those pins as well.. 
//recall: cfg 1 = outut, 0=intput
//mov 	r0, 0b1111100100000000 //configs port a
//outp 	r0, GPAcfg
//mov 	r0, 0b0001111111111111 //configs port d
//outp 	r0, GPDcfg
//mov 	r0, 0b1111100011111111 //configs port G
//outp 	r0, GPGcfg
/////////////////////////////////////
//***Hardware Setup Info*********
//Following connections on board:
//  A2 (need to reroute from pin11)
// 

//  D7   A1   A2    A3   A4   C0    C1   C7     <-- use this one
//Corresponding Buttons
// TLeft TMid TRght Rght LFT  Up  Dwn  Centre   //USE THIS CONNECTION
//  Up   Lft  Rht   Dwn  Cntr Tleft Tmid TRight (alternate connect)


//////////////////////
//		CHANGELOG:   
//March 23 - 13:21 - Fixed the code to work with inverted logic.

//CODE

/////////////////////////////////////////////////////////////////////
//function: GetButtonEvent
//description: Listens for a button press, returns a vector of what action should be done based on a certain button mask for a specified menu
//      Will only return first button pressed, no menus or w/e require two button presses.
//  only returns when a button is pressed. (at least now, may put in a time loop to make sure it can break out)
//input arguments: none
//output arguments: R1-> vector of what button was pressed in following order 
//    2nd MSB->LSB   tpLeft tpMiddle tpRight UP LEFT CENTRE RIGHT DOWN
//      0x00ML
//written by: marcin
//
//example:    jsr r6, GetButtonEvent
//  //r1 now has output of which button was pressed 
//////////////////////////////////////////////////////////////////////

GetButtonEvent:
 st  r0, sp, 0 	 //GPDout store 
 st  r1, sp, 1 //output var: which button was pressed; see above for translation
 st r2, sp, 2 //scratch
 st  r3, sp, 3 	//GPAout store
 st r4, sp, 4 	//GPCout store
 st r5, sp, 5 	//scratch
 
 st  r6, sp, 6
 add sp, sp, 7
 
 mov r1, 0   //used as counter and output variable
GetButtonEventLoop:
 inp r0, GPDin
 inp r3, GPAin
 inp r4, GPCin



//NOTE: buttons are using inverted logic. 1 = off, 0 = on
 //mov r2, 0x0080  //bitmask for pin D7/
 bix	r0, r0, 7 //back into non-inverted logic
 and r2, r0, 0x0080  //checks for d7/IP, resolves to zero if pressed
 bc ZS, GBNextStart
 mov r2, 0x0080 // mask 010 and input 000 = zero if present. 
 bra GetButtonEnd
 
//fixed, noninverted
 
 GBNextStart:
 
 //mov r2, 0x0002  //bitmask for A1 
 bix	r3, r3, 1
 and r2, r3, 0x0002
 bc ZS, GBNext0 //if no input (nonzero) jump over next part
 //fixed, inverted logic, use ZC to detect input=1 (off)
 mov r2, 0x0040 //detected 
 bra GetButtonEnd //found input skip to end
//fixed, noninverted

 GBNext0:
 //mov r2, 0x0004//bitmask for A2 
 bix	r3, r3, 2
 and r2, r3, 0x0004
 bc ZS, GBNext //if no input (nonzero) jump over next part
 mov r2, 0x0020
 bra GetButtonEnd //found input skip to end
//fixed, noninverted

GBNext:
// mov r2, 0x0008   //bitmask for A3
 bix	r3, r3, 3
 and r2, r3, 0x0008
 bc ZS, GBNext1  //ifnotinput, jump over next part
 mov r2, 0x0010  //output for a3
 bra GetButtonEnd
//fixed, noninverted

GBNext1:
// mov 	r2, 0x0010   //bitmask for A4  
 bix	r3, r3, 4
 and 	r2, r3, 0x0010
 bc 	ZS, GBNext2  
 mov 	r2, 0x0008
 bra GetButtonEnd
 //fixed, noninverted
 
 GBNext2:
 //mov 	r2, 0x0001 //bitmask for C0
 bix 	r4, r4, 0
 and 	r2, r4, 0x0001
 bc 	ZS, GBNext3 //will zset 0 if input present
 mov 	r2, 0x0004 //output for C0
bra GetButtonEnd
//fixed, noninverted

 GBNext3:
// mov 	r2, 0x0002 //bitmask for C1
 bix r4, r4, 1
 and 	r2, r4, 0x0002
 bc 	ZS, GBNext4 //will Zset if input present
 mov	r2, 0x0002
 bra GetButtonEnd 
//fixed, noninverted

GBNext4:
//mov 	r2, 0x0080 //bitmask for c7
bix	r4, r4, 7
and 	r2, r4, 0x0080
bc 	ZS, GBNext5 //willZset if input present
mov	r2, 0x0001
bra	GetButtonEnd
//fixed, noninverted
GBNext5:
  // if code gets here, no button has been pressed, loop forever (need to change this, set a reasonable loop)
mov r2, 0x0000 //output from this routine will be 0x0000 if no button was pressed 



GetButtonEnd:
 mov r1, r2 //moves vector of button presses to r1
 sub sp, sp, 7
 ld r0, sp, 0
 //ld r1, sp, 1 // Dont want to restore r1, since our output is coming off it
 ld r2, sp, 2
 ld  r3, sp, 3
 ld r4, sp, 4
 ld  r5, sp, 5
 ld r6, sp, 6
 jsr r6, r6
 
////////////////////////////////////